package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.CategoryDTO;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    public PageResult<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {

        PageHelper.startPage(page, rows);


        Example example = new Example(Spu.class);

        Example.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotBlank(key)) {//根据key模糊查询

            criteria.andLike("name", "%" + key + "%");
        }

        //根据saleable，
        if (null != saleable) {
            criteria.andEqualTo("saleable", saleable);
        }

        List<Spu> spus = this.spuMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(spus)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        //统计分页信息
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(spus, SpuDTO.class);

        spuDTOS.forEach(spuDTO -> {

            // 查询分类  查询得到了分类的DTO的集合，并把集合循环遍历，取出每个name，并且拼接成一个字符串
            //手机/手机通讯/手机
            String categoryName = categoryService.queryCategoryByIds(spuDTO.getCategoryIds())
                    .stream()
                    .map(CategoryDTO::getName).collect(Collectors.joining("/"));

            //根据分组的id查询对应的分组的信息，
            spuDTO.setCategoryName(categoryName);

            //根据品牌的id，查询品牌的信息
            spuDTO.setBrandName(this.brandService.queryBrandById(spuDTO.getBrandId()).getName());
        });

        return new PageResult<>(pageInfo.getTotal(), pageInfo.getPages(), spuDTOS);
    }

    @Transactional
    public void save(SpuDTO spuDTO) {
        //1,保存spu

        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        //spu缺失saleable
        spu.setSaleable(true);

        //保存sku并回显spu id
        int count = this.spuMapper.insertSelective(spu);

        if (1!=count){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

        //2,保存spuDetail

        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        //spuDetail缺失spuId
        spuDetailDTO.setSpuId(spu.getId());

        count = this.spuDetailMapper.insertSelective(BeanHelper.copyProperties(spuDetailDTO,SpuDetail.class));

        if (1!=count){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

        //3,保存sku

        List<SkuDTO> skus = spuDTO.getSkus();

        skus.forEach(sku->{
            //sku也缺失spuId
            sku.setSpuId(spu.getId());
            this.skuMapper.insertSelective(BeanHelper.copyProperties(sku,Sku.class));
        });

    }

    public SpuDetailDTO querySpuDetailById(Long spuId) {

        SpuDetail spuDetail = this.spuDetailMapper.selectByPrimaryKey(spuId);

        return BeanHelper.copyProperties(spuDetail,SpuDetailDTO.class);
    }

    public List<SkuDTO> querySkuBySpuId(Long spuId) {

        Sku record = new Sku();

        record.setSpuId(spuId);

        List<Sku> select = this.skuMapper.select(record);

        if (CollectionUtils.isEmpty(select)){
                throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        return BeanHelper.copyWithCollection(select,SkuDTO.class);
    }


    @Autowired
    private AmqpTemplate amqpTemplate;

    public void updateSaleable(Long id, Boolean saleable) {
        Spu record = new Spu();

        record.setId(id);
        record.setSaleable(saleable);

        this.spuMapper.updateByPrimaryKeySelective(record);


        String key=saleable ? ITEM_UP_KEY : ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,key,id);
    }

    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        //修改spu

        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setUpdateTime(new Date());

        int count = this.spuMapper.updateByPrimaryKeySelective(spu);

        if (1!=count){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //修改spuDetail
        this.spuDetailMapper.updateByPrimaryKeySelective(BeanHelper.copyProperties(spuDTO.getSpuDetail(),SpuDetail.class));

        //sku的修改,首先删除之前所有的sku

        Sku record = new Sku();
        //删除spuId为当前id所有的sku
        record.setSpuId(spuDTO.getId());

        this.skuMapper.delete(record);

        //重新新增sku


        List<SkuDTO> skus = spuDTO.getSkus();

        skus.forEach(sku->{
            //sku也缺失spuId
            sku.setSpuId(spu.getId());
            this.skuMapper.insertSelective(BeanHelper.copyProperties(sku,Sku.class));
        });
    }


    public SpuDTO querySpuById(Long id) {
        Spu spu = spuMapper.selectByPrimaryKey(id);
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        spuDTO.setSpuDetail(querySpuDetailById(id));
        spuDTO.setSkus(querySkuBySpuId(id));
        return spuDTO;
    }

    public List<SkuDTO> querySkuByIds(List<Long> ids) {
        List<Sku> skus = this.skuMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skus,SkuDTO.class);
    }

    @Transactional
    public void minusStock(Map<Long, Integer> cartMap) {
        for(Map.Entry<Long,Integer> entry:cartMap.entrySet()){
            Long skuId = entry.getKey();
            Integer num = entry.getValue();
            int count=skuMapper.minusStock(skuId,num);
            if(count!=1){
                throw new RuntimeException("库存不足！");
            }
        }
    }
}
